home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / gnustuff / minix / libsrc~1.z / libsrc~1 / termcap.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-12-28  |  7.1 KB  |  373 lines

  1. /* EFTH MINIX report #64  - February 1989 -  termcap(3) */
  2.  
  3. /*
  4.  *    termcap.c    V1.1    20/7/87        agc    Joypace Ltd
  5.  *
  6.  *    Copyright Joypace Ltd, London, UK, 1987. All rights reserved.
  7.  *    This file may be freely distributed provided that this notice
  8.  *    remains attached.
  9.  *
  10.  *    A public domain implementation of the termcap(3) routines.
  11.  *
  12.  *
  13.  *
  14.  *     Klamer Schutte          V1.2    Nov. 1988
  15.  *
  16.  *   - Can match multiple terminal names         [tgetent]
  17.  *   - Removal of **area assignments             [tgetstr]
  18.  *
  19.  *     Terrence W. Holm     V1.3    May, Sep, Oct.  1988
  20.  *
  21.  *   - Correct when TERM != name and TERMCAP is defined     [tgetent]
  22.  *   - Correct the comparison for the terminal name      [tgetent]
  23.  *   - Correct the value of ^x escapes                   [tgetstr]
  24.  *   - Added %r to reverse row/column             [tgoto]
  25.  *   - Fixed end of definition test             [tgetnum/flag/str]
  26.  *
  27.  *     Terrence W. Holm     V1.4    Jan. 1989
  28.  *
  29.  *   - Incorporated Klamer's V1.2 fixes into V1.3
  30.  *   - Added %d, (old %d is now %2)             [tgoto]
  31.  *   - Allow '#' comments in definition file         [tgetent]
  32.  */
  33.  
  34. #include <stdio.h>
  35. #include <ctype.h>
  36. #include <sys/types.h>
  37. #include <unistd.h>
  38. #include <string.h>
  39.  
  40. char    *capab = NULL;        /* the capability itself */
  41.  
  42. /*  The following are not yet used.  */
  43. extern short    ospeed;        /* output speed */
  44. extern char    PC;        /* padding character */
  45. extern char    *BC;        /* back cursor movement */
  46. extern char    *UP;        /* up cursor movement */
  47.  
  48.  
  49. #ifndef __STDC__
  50. extern char    *getenv();
  51. extern FILE    *fopen();
  52. #else
  53.     /* pick up proto from <std.h> */
  54. #endif
  55.  
  56.  
  57. /*
  58.  *    tgetent - get the termcap entry for terminal name, and put it
  59.  *    in bp (which must be an array of 1024 chars). Returns 1 if
  60.  *    termcap entry found, 0 if not found, and -1 if file not found.
  61.  */
  62.  
  63. int
  64. tgetent(bp, name)
  65. char    *bp;
  66. _CONST char    *name;
  67. {
  68.     FILE    *fp;
  69.     char    *file;
  70.     char     *term;
  71.     short    len = strlen(name);
  72.  
  73.     capab = bp;
  74.  
  75.     /*  If TERMCAP begins with a '/' then use TERMCAP as the path    */
  76.     /*  name of the termcap definitions file. If TERMCAP is a    */
  77.     /*  definition and TERM equals "name" then use TERMCAP as the    */
  78.     /*  definition. Otherwise use "/etc/termcap" as the path name.    */
  79.  
  80.     if ( (file = getenv("TERMCAP")) == NULL )
  81.         file = "/etc/termcap";
  82.     else if ( *file != '/' )
  83.         if ( (term = getenv("TERM")) != NULL && strcmp(term, name) == 0 ) {
  84.         *bp = '\0';
  85.         strncat( bp, file, 1023 );
  86.         return(1);
  87.         } else
  88.         file = "/etc/termcap";
  89.  
  90.     if ((fp = fopen(file, "r")) == (FILE *) NULL) {
  91.         capab = NULL;        /* no valid termcap  */
  92.         return(-1);
  93.     }
  94.  
  95.      for (;;) {
  96.         /*  Read in each definition */
  97.         int def_len = 0;
  98.         char *cp = bp;
  99.  
  100.         do {
  101.             if ( fgets(&bp[def_len], 1024-def_len, fp) == NULL ) {
  102.                 fclose(fp);
  103.                 capab = NULL;    /* no valid termcap */
  104.                 return(0);
  105.             }
  106.  
  107.             def_len = strlen(bp) - 2;
  108.         } while( bp[def_len] == '\\' );
  109.  
  110.         while ( isspace(*cp) )
  111.             cp++;
  112.  
  113.         /*  Comment lines start with a '#'  */
  114.         if ( *cp == '#' )
  115.             continue;
  116.  
  117.         /*  See if any of the terminal names in this definition */
  118.         /*  match "name".                    */
  119.  
  120.         do {
  121.             if ( strncmp(name, cp, len) == 0  &&
  122.                 ( cp[len] == '|'  ||  cp[len] == ':' ) ) {
  123.                  fclose(fp);
  124.                 return(1);
  125.             }
  126.  
  127.             while( (*cp) && (*cp != '|') && (*cp != ':'))
  128.                 cp++;
  129.         } while( *cp++ == '|');
  130.     }
  131. }
  132.  
  133.  
  134.  
  135. /*
  136.  *    tgetnum - get the numeric terminal capability corresponding
  137.  *    to id. Returns the value, -1 if invalid.
  138.  */
  139.  
  140. int
  141. tgetnum(id)
  142. _CONST char    *id;
  143. {
  144.     register  char *cp = capab;
  145.  
  146.     if (cp == NULL || id == NULL)
  147.         return(-1);
  148.  
  149.     for(;;) {
  150.         while (*cp++ != ':')
  151.             if (cp[-1] == '\0')
  152.                 return(-1);
  153.  
  154.         while (isspace(*cp))
  155.             cp++;
  156.  
  157.         if (strncmp(cp, id, 2) == 0  &&  cp[2] == '#' )
  158.             return( atoi(cp+3) );
  159.     }
  160. }
  161.  
  162.  
  163.  
  164. /*
  165.  *    tgetflag - get the boolean flag corresponding to id. Returns -1
  166.  *    if invalid, 0 if the flag is not in termcap entry, or 1 if it is
  167.  *    present.
  168.  */
  169.  
  170. int
  171. tgetflag(id)
  172. _CONST char    *id;
  173. {
  174.     register  char *cp = capab;
  175.  
  176.     if (cp == NULL || id == NULL)
  177.         return(-1);
  178.  
  179.     for (;;) {
  180.         while (*cp++ != ':')
  181.             if (cp[-1] == '\0')
  182.                 return(0);
  183.  
  184.         while (isspace(*cp))
  185.             cp++;
  186.  
  187.         if (strncmp(cp, id, 2) == 0)
  188.             return(1);
  189.     }
  190. }
  191.  
  192.  
  193.  
  194. /*
  195.  *    tgetstr - get the string capability corresponding to id and place
  196.  *    it in area (advancing area at same time). Expand escape sequences
  197.  *    etc. Returns the string, or NULL if it can't do it.
  198.  */
  199.  
  200. char *
  201. tgetstr(id, area)
  202. _CONST char    *id;
  203. char    **area;
  204. {
  205.     register  char *cp  = capab;
  206.     register  char *wsp = *area;    /*  workspace pointer  */
  207.  
  208.     if (cp == NULL || id == NULL)
  209.         return(NULL);
  210.  
  211.     for (;;) {
  212.         while (*cp++ != ':')
  213.             if (cp[-1] == '\0')
  214.                 return(NULL);
  215.  
  216.         while (isspace(*cp))
  217.             cp++;
  218.  
  219.         if (strncmp(cp, id, 2) == 0  &&  cp[2] == '=' ) {
  220.             for (cp+=3;  *cp && *cp != ':'  ; wsp++, cp++)
  221.                 switch(*cp) {
  222.                 case '^' :
  223.                     *wsp = *++cp - '@';
  224.                     break;
  225.  
  226.                 case '\\' :
  227.                     switch(*++cp) {
  228.                     case 'E' :
  229.                         *wsp = '\033';
  230.                         break;
  231.                     case 'n' :
  232.                         *wsp = '\n';
  233.                         break;
  234.                     case 'r' :
  235.                         *wsp = '\r';
  236.                         break;
  237.                     case 't' :
  238.                         *wsp = '\t';
  239.                         break;
  240.                     case 'b' :
  241.                         *wsp = '\b';
  242.                         break;
  243.                     case 'f' :
  244.                         *wsp = '\f';
  245.                         break;
  246.                     case '0' :
  247.                     case '1' :
  248.                     case '2' :
  249.                     case '3' :
  250.                         {
  251.                         int i;
  252.                         int t = 0;
  253.                         for (i=0; i<3  &&
  254.                             isdigit(*cp) ; ++i, ++cp)
  255.                                t = t * 8 + *cp - '0';
  256.                         *wsp = t;
  257.                         cp--;
  258.                         break;
  259.                         }
  260.                     default:
  261.                         *wsp = *cp;
  262.                     }
  263.                     break;
  264.  
  265.                 default :
  266.                     *wsp = *cp;
  267.                 }
  268.  
  269.             *wsp++ = '\0';
  270.  
  271.             {
  272.             char *ret = *area;
  273.             *area = wsp;
  274.             return(ret);
  275.             }
  276.         }
  277.     } /* end for(;;) */
  278. }
  279.  
  280.  
  281.  
  282. /*
  283.  *    tgoto - given the cursor motion string cm, make up the string
  284.  *    for the cursor to go to (destcol, destline), and return the string.
  285.  *    Returns "OOPS" if something's gone wrong, or the string otherwise.
  286.  */
  287.  
  288. char *
  289. tgoto(cm, destcol, destline)
  290. _CONST char    *cm;
  291. int    destcol;
  292. int    destline;
  293. {
  294.     static  char  ret[24];
  295.     char   *rp    = ret;
  296.     int    incr  = 0;
  297.     int     argno = 0;
  298.     int    numval;
  299.  
  300.     for ( ; *cm ; cm++) {
  301.         if ( *cm == '%' ) {
  302.             switch(*++cm) {
  303.             case 'i' :
  304.                 incr = 1;
  305.                 break;
  306.  
  307.             case 'r' :
  308.                 argno = 1;
  309.                 break;
  310.  
  311.             case '+' :
  312.                 numval = (argno == 0 ? destline : destcol);
  313.                 *rp++ = numval + incr + *++cm;
  314.                 argno = 1 - argno;
  315.                 break;
  316.  
  317.             case '2' :
  318.                 numval = (argno == 0 ? destline : destcol);
  319.                 numval = (numval + incr) % 100;
  320.                 *rp++ = '0' + (numval/10);
  321.                 *rp++ = '0' + (numval%10);
  322.                 argno = 1 - argno;
  323.                 break;
  324.  
  325.             case 'd' :
  326.                 numval = (argno == 0 ? destline : destcol);
  327.                 numval = (numval + incr) % 1000;
  328.                 if ( numval > 99 )
  329.                     *rp++ = '0' + (numval/100);
  330.                 if ( numval > 9 )
  331.                     *rp++ = '0' + (numval/10) % 10;
  332.                 *rp++ = '0' + (numval%10);
  333.                 argno = 1 - argno;
  334.                 break;
  335.  
  336.             case '%' :
  337.                 *rp++ = '%';
  338.                 break;
  339.  
  340.             default :
  341.                 return( "OOPS" );
  342.             }
  343.  
  344.         } else
  345.             *rp++ = *cm;
  346.     }
  347.  
  348.     *rp = '\0';
  349.     return(ret);
  350. }
  351.  
  352.  
  353.  
  354. /*
  355.  *    tputs - put the string cp out onto the terminal, using the function
  356.  *    outc. This should do padding for the terminal, but I can't find a
  357.  *    terminal that needs padding at the moment...
  358.  */
  359.  
  360. int
  361. tputs(cp, affcnt, outc)
  362. _CONST register char    *cp;
  363. int        affcnt;
  364. int        (*outc)();
  365. {
  366.     if (cp == NULL)
  367.         return(1);
  368.     /* do any padding interpretation - left null for MINIX just now */
  369.     while (*cp)
  370.         (*outc)(*cp++);
  371.     return(1);
  372. }
  373.